/*
 moxl - Modular XML Library
 Copyright (c) 2007, Malcolm Sparks

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package moxl.xpath.parser.types;

import java.util.ArrayList;
import java.util.List;

import moxl.dom.MoxlNode;
import moxl.xpath.XPathContext;

public class Predicate
{
	private final Expression expr;

	public Predicate(Expression expr)
	{
		this.expr = expr;
	}

	public List<MoxlNode> filterSet(XPathContext context, List<MoxlNode> unfilteredNodeSet) throws XPathEvaluationException
	{
		List<MoxlNode> resultSet = new ArrayList<MoxlNode>();
		int contextSize = unfilteredNodeSet.size();
		for (int contextPosition = 1; contextPosition <= contextSize; contextPosition++)
		{
			MoxlNode node = unfilteredNodeSet.get(contextPosition - 1);
			XPathContext childContext = context.beget(node, contextPosition, contextSize);
			AbstractXPathValue evaluationResult = expr.evaluate(childContext);
			if (evaluationResult instanceof XPathBooleanValue)
			{
				if (((XPathBooleanValue) evaluationResult).getValueAsBoolean())
				{
					resultSet.add(node);
				}
			}
			else if (evaluationResult instanceof XPathNumberValue)
			{
				XPathNumberValue numberValue = (XPathNumberValue) evaluationResult;
				if (contextPosition == numberValue.getValueAsDouble())
				{
					resultSet.add(node);
				}
			}
			else
			{
				throw new XPathEvaluationException("Evaluation of predicate " + this + " on " + childContext.getContextNode() + " yields an unexpected type: "
				        + evaluationResult.getClass().getName());
			}
		}
		return resultSet;
	}
}
